#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2020/6/22 14:33
# @Author : wn 
# @File: paper.py
# @SoftWare: PyCharm
# @Site:
# @Table:
# ｡◕‿◕｡｡◕‿◕｡｡◕‿◕｡

import json
from operator import itemgetter

from django.db.models import Max
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.views import View

from trade.OperationLog import OperationLog
from trade.model_choices import *
from trade.models import *
from trade.search_page import searchs_paper
from utils.chardate import chardate
from utils.service import my_page


class Paper(View):
    '''
    仿真策略
    '''

    def __init__(self):
        self.title = "仿真列表"
        self.url = '/trade/paper'
        self.opt = '提交实盘'

    def get(self, request):
        # 当前访问用户
        customerid = request.GET.get('customerid', None)
        if customerid:
            request.session['customerid'] = customerid
            print('get方式，当前访问的用户是：', customerid)

        # 当前在第几页
        off = request.GET.get('offset', None)
        # 一页几条
        lim = request.GET.get('limit', None)
        # get请求申请实盘的value
        get_askfor_live = request.GET.get('askForLive_stgid', None)
        if lim is None and get_askfor_live is not None:
            # 策略表
            stg_list = list(Strategy.objects.filter(stgid=int(get_askfor_live)))  # [StragegyObj,]
            for item in stg_list:
                result_dict = {}
                result_dict['stgid'] = item.stgid  # int
                result_dict['stgname'] = item.stgname
                result_dict['stggroup'] = StgGroup.get(item.stggroup, None)
                # 仿真策略审批表中的环境名
                paperapp_list = list(Paperapproval.objects.filter(stgid=item.stgid))
                if paperapp_list is not None and len(paperapp_list) != 0:
                    result_dict['envname'] = paperapp_list[0].envid
                # 仿真策略参数表
                paperpara_list = list(Paperstgpara.objects.filter(stgid=item.stgid))
                if paperpara_list is not None and len(paperpara_list) != 0:
                    pararry = []
                    for i, obj in enumerate(paperpara_list):
                        para_dict = {}
                        para_dict['paraname'] = obj.propkey
                        para_dict['paravalue'] = obj.propvalue
                        para_dict['paradesc'] = obj.description
                        pararry.append(para_dict)
                    result_dict['pararry'] = pararry
            result = my_page([result_dict], lim, off)
            return JsonResponse(result, safe=False)

        if lim is None:
            envs_obj = Environment.objects.all()
            html = "paper.html" if self.url == "/trade/paper" else "paperApproval.html"
            return render(request, html, {'url': self.url, 'title': self.title, 'envs_obj': envs_obj})
        else:
            tab_type = request.GET.get("type")
            result_list = []
            # 打包列表的[]
            item_approval_pack_list = []
            # 策略表
            stg_list = list(Strategy.objects.all())
            for item in stg_list:
                # 都打包成功
                isPackStatus = True
                result_dict = {}
                result_dict['stgid'] = item.stgid
                result_dict['stgname'] = item.stgname
                result_dict['createtime'] = item.createtime
                result_dict['backupdatetime'] = item.backupdatetime
                result_dict['backtest'] = item.backtest
                result_dict['status'] = item.status
                result_dict['stgfile'] = item.stgfile
                result_dict['stggroup'] = item.stggroup
                result_dict['paperisdelete'] = item.paperisdelete
                result_dict['customerid'] = item.customerid
                # 仿真策略审批表
                paperapp_list = list(Paperapproval.objects.filter(stgid=item.stgid))
                if paperapp_list is not None and len(paperapp_list) != 0:
                    result_dict['auditstatus'] = AuditStatus.get(paperapp_list[0].auditstatus, None)
                    result_dict['updatetime'] = paperapp_list[0].updatetime
                    result_dict['auditmsg'] = paperapp_list[0].auditmsg
                    # result_dict['packstatus'] = PackStatus_ModelChoices.get(paperapp_list[0].packstatus, None)
                    # result_dict['packmsg'] = paperapp_list[0].packmsg
                    # result_dict['packtime'] = paperapp_list[0].packtime

                    # 打包列表的[]
                    for item_approval_packstatus in paperapp_list:
                        item_approval_pack_dict = {}
                        item_approval_pack_dict['stgid'] = item.stgid
                        item_approval_pack_dict['stgname'] = item.stgname
                        item_approval_pack_dict['packstatus'] = PackStatus_ModelChoices.get(item_approval_packstatus.packstatus,None)
                        item_approval_pack_dict['packmsg'] = item_approval_packstatus.packmsg
                        item_approval_pack_dict['packtime'] = item_approval_packstatus.packtime
                        envObj = Environment.objects.filter(envid=item_approval_packstatus.envid)[0]
                        item_approval_pack_dict['envname'] = envObj.envname
                        item_approval_pack_dict['backtype'] = BackType.get(envObj.backtype,None)
                        item_approval_pack_dict['poption'] = str(item.stgid) + "_" + str(item_approval_packstatus.envid)  # 打包列表
                        if item_approval_packstatus.auditstatus == "3":
                            item_approval_pack_list.append(item_approval_pack_dict)
                        # 打包不成功
                        if item_approval_packstatus.packstatus != '1':
                            isPackStatus = False

                    # 环境表
                    # env_list = list(Environment.objects.filter(envid=paperapp_list[0].envid))
                    # if env_list is not None and len(env_list) != 0:
                    #     result_dict['envname'] = env_list[0].envname + "(" + env_list[0].ip + ")"

                # 仿真运行表
                paperrun_list = list(Paperrun.objects.filter(stgid=item.stgid))
                if paperrun_list is not None and len(paperrun_list) != 0:
                    result_dict['starttime'] = paperrun_list[0].starttime
                    result_dict['endtime'] = paperrun_list[0].endtime
                    result_dict['runstatus'] = StgRunStatus.get(paperrun_list[0].runstatus, None)

                # 策略在实盘审批表中的审批状态
                result_dict['aud_status_live'] = '-1.1'
                status_live_len = Liveapproval.objects.filter(stgid=item.stgid)
                if len(status_live_len) == 1 and len(status_live_len) > 0:
                    auditstatus_tuple = status_live_len.values_list('auditstatus')[0]
                    aud_status_live = list(auditstatus_tuple)[0]
                    result_dict['aud_status_live'] = aud_status_live
                elif len(status_live_len) > 1:
                    updatetime = status_live_len.aggregate(Max('inserttime'))
                    ut = updatetime['inserttime__max']
                    stgid_update_la = Liveapproval.objects.filter(stgid=item.stgid, inserttime=ut)
                    auditstatus_tuple = stgid_update_la.values_list('auditstatus')[0]
                    aud_status_live = list(auditstatus_tuple)[0]
                    result_dict['aud_status_live'] = aud_status_live

                # my_columns，操作的field 的值
                result_dict['uoption'] = item.stgid  # 上传列表
                # result_dict['poption'] = item.stgid  # 打包列表
                result_dict['soption'] = item.stgid  # 仿真列表
                result_dict['approval_option'] = item.stgid  # 仿真策略审批

                # "1":打包列表，"2":仿真列表,"0":上传列表
                if tab_type == "1":
                    result_list = item_approval_pack_list
                elif tab_type == "2" and isPackStatus and item.paperisdelete == 1 and \
                        result_dict['auditstatus'] == "审批通过":
                    result_list.append(result_dict)
                elif tab_type == "0":
                    result_list.append(result_dict)
            # 排序
            for item in result_list:
                if (item.get('stgid') is None):
                    item['stgid'] = '-1'
            result_list_sorted = sorted(result_list, key=itemgetter('stgid'), reverse=True)
            result = my_page(result_list_sorted, lim, off)
            return JsonResponse(result, safe=False)

    def post(self, request):
        # 仿真列表，状态非启动时，只删除页面显示，修改paperisdelete = 0
        if request.POST.get('delete_paper_list', None):
            stgid = int(request.POST.get('id'))  # int(str)
            Strategy.objects.filter(stgid=stgid).update(
                paperisdelete=0,
            )

            # 操作日志 	删除策略：包括两种，上传策略后的物理删除策略、审批通过后的连接删除，记录删除人员、删除时间、删除策略ID、删除策略名
            stg = Strategy.objects.filter(stgid=stgid)[0]
            stgname = stg.stgname
            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '2',
                'optinfo': '删除策略_页面删除，策略ID：%s，策略名称：%s' % (
                    stgid, stgname),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict)

            return HttpResponse('y')
        elif request.POST.get('delete', None):
            # request.POST.get('delete', None) str 1，上传列表非审批状态的删除
            # 删除
            stgid = int(request.POST.get('id'))  # int(str)

            # 操作日志,物理删除
            stg = Strategy.objects.filter(stgid=stgid)
            if len(stg) != 0:
                stg = stg[0]
                stgname = stg.stgname
                customerid_log = request.session.get('id', 'noCid')
                log_dict = {
                    'customerid': customerid_log,
                    'modular': '1',
                    'optfunction': '2',
                    'optinfo': '删除策略，策略ID：%s，策略名称：%s' % (
                        stgid, stgname),
                    'opttime': chardate(),
                }
                OperationLog.opt_log(log_dict)

            # 策略对应的参数表
            Paperstgpara.objects.filter(stgid=stgid).delete()

            # 策略对应的审批表
            pa = Paperapproval.objects.filter(stgid=stgid).values_list('auditstatus')
            if pa is not None and len(pa) != 0:
                for item in pa:
                    list_auditstatus = list(item)[0]  # str 1
                    if list_auditstatus == '3':
                        delete_msg = "审批已通过，无法删除！"
                        return HttpResponse(delete_msg)
                    else:
                        Strategy.objects.filter(stgid=stgid).delete()
                        Paperapproval.objects.filter(stgid=stgid).delete()
            return HttpResponse('y')
        elif request.POST.get('stg_pack', None):
            # 打包，仿真策略审批表打包状态=='0'
            stgid_envid = request.POST.get('id')  # str
            se_list = stgid_envid.split('_')
            # 打包，实盘策略审批表打包状态=='0'
            stgid = int(se_list[0])  # int(str)
            Paperapproval.objects.filter(stgid=stgid,envid=se_list[1]).update(
                packstatus='0',
                packmsg='',
            )

            # 操作日志 	手工打包：记录申请打包时间、打包人员、打包结果
            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '3',
                'optinfo': '手工打包，申请人：%s，打包时间：%s，打包结果：%s' % (
                    customerid_log, chardate(), '手工打包成功'),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict)

            return HttpResponse('y')
        elif request.POST.get('stg_pack_error', None):
            stgid_envid = request.POST.get('id')  # str
            se_list = stgid_envid.split('_')
            # 打包，实盘策略审批表打包状态=='0'
            stgid = int(se_list[0])  # int(str)
            packmsg_qs = Paperapproval.objects.filter(stgid=stgid,envid=se_list[1]).values_list(
                'packmsg')  # [('',)('缺少python')] -- [list(('',))][0][0]
            packmsg = ''
            if len(packmsg_qs) != 0:
                packmsg = list(packmsg_qs[0])[0]
            return JsonResponse({'packmsg': packmsg})
        elif request.POST.get('askfor_live_sub', None):
            # 申请实盘
            data = request.POST
            stgid = json.loads(data["data[stgid_askfor_live]"])[0]  # str
            stgname = json.loads(data["data[stgname_askfor_live]"])[0]  # str
            envname = json.loads(data["data[envname_askfor_live]"])[0]  # str
            # 实盘策略审批,根据环境表中type==2的生成实盘审批记录
            envs = Environment.objects.filter(type=2)
            inserttime_approval = chardate()
            for item_env in envs:
                if not Liveapproval.objects.filter(stgid=stgid, envid=item_env.envid,auditstatus='1').exists():
                    Liveapproval.objects.create(
                        stgid=stgid,
                        envid=item_env.envid,
                        remark='',
                        audittime='',
                        inserttime=inserttime_approval,
                        auditstatus='1',
                        auditmsg='',
                        packstatus='',
                        packmsg='',
                        packtime='',
                    )
            # 实盘参数表
            pararry_list = json.loads(
                data["data[pararry_askfor_live]"])  # dict,[{paraname:'',paravalue:'',paradesc:''},{},{}]
            for livepara in pararry_list:
                paraname = livepara['paraname']
                paravalue = livepara['paravalue']
                paradesc = livepara['paradesc']
                if not Livestgpara.objects.filter(stgid=int(stgid), propkey=paraname).exists():
                    Livestgpara.objects.create(
                        stgid=int(stgid),
                        propkey=paraname,
                        propvalue=paravalue,
                        description=paradesc,
                        proptype='',
                        provalueitems='',
                        updatetime=chardate(),
                    )

            # 操作日志，记录申请实盘的策略ID、策略名、申请人、申请时间
            stg = Strategy.objects.filter(stgid=stgid)[0]
            stgname = stg.stgname
            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '9',
                'optinfo': '申请实盘，策略ID：%s，策略名称：%s，申请人：%s，申请时间：%s' % (
                    stgid, stgname, customerid_log, inserttime_approval),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict)
            return HttpResponse('y')
        elif request.POST.get('upload_search', None):
            # 前端查询条件
            data = json.loads(request.POST.get("data"))
            stgid_search = data.get("stgid", None)  # if no condition value is str ''
            stgname_search = data.get("stgname", None)  # str ''
            auditstatus_search = data.get("auditstatus", None)

            jsonRes = searchs_paper(stgid_search=stgid_search, stgname_search=stgname_search,
                                    auditstatus_search=auditstatus_search)
            return jsonRes
        elif request.POST.get('pack_search', None):
            # 前端查询条件
            data = json.loads(request.POST.get("data"))
            pstgname = data.get("pstgname", None)  # if no condition value is str ''
            ppackstatus = data.get("ppackstatus", None)  # if no condition value is str ''
            jsonRes = searchs_paper(stgname_search=pstgname, packstatus_search=ppackstatus, type='packList')
            return jsonRes
        elif request.POST.get('paper_search', None):
            # 前端查询条件
            data = json.loads(request.POST.get("data"))
            sstgid = data.get("sstgid", None)  # if no condition value is str ''
            sstgname = data.get("sstgname", None)  # if no condition value is str ''
            sstgstatus = data.get("sstgstatus", None)  # if no condition value is str ''
            jsonRes = searchs_paper(stgid_search=sstgid, stgname_search=sstgname, stgrunstatus_search=sstgstatus,
                                    type='paperList')
            return jsonRes

        else:
            '''
            基于web自动生成的策略编号赋值， 
            算法策略以50001开始递增，其他策略以10001开始递增
            Strategy_ID = 10001
            '''
            # 上传策略，写入策略表，仿真策略审批表，仿真策略参数表
            data = request.POST
            stggroup_other = 10001
            stggroup_sf = 50001
            stggroup_3 = Strategy.objects.filter(stggroup='3').aggregate(Max('stgid'))
            stggroup_1_2 = Strategy.objects.exclude(stggroup='3').aggregate(Max('stgid'))
            if json.loads(data['stggroup'])[0] == '3':
                # 算法策略组
                if stggroup_3['stgid__max']:
                    stgid = stggroup_3['stgid__max'] + 1
                else:
                    stgid = stggroup_sf
            else:
                # 非算法策略组
                if stggroup_1_2['stgid__max']:
                    stgid = stggroup_1_2['stgid__max'] + 1  # int + int
                else:
                    stgid = stggroup_other
            filt = json.loads(data["file"])[0]
            # 新增 策略表
            createtime = chardate()
            Strategy.objects.create(
                stgid=stgid,
                stgname=json.loads(data["stgname"])[0],
                stggroup=json.loads(data["stggroup"])[0],
                stgfile=filt,
                createtime=createtime,
                backupdatetime=chardate(),
                customerid=request.session.get('id', ''),
                backtest=-1,
                status='',
                paperisdelete=1,
                liveisdelete=1,
            )

            # 根据环境表中type==1的条数生产审批表记录
            envs = Environment.objects.filter(type=1)
            for env in envs:
                Paperapproval.objects.create(
                    stgid=stgid,
                    envid=env.envid,
                    remark='',
                    updatetime='',
                    auditstatus='1',
                    auditmsg='',
                    packstatus='',
                    packmsg='',
                    packtime='',
                )

            # 仿真策略参数
            para_list = json.loads(data['pararry'])
            for item in para_list:
                stg_name = item['paraname']
                stg_value = item['paravalue']
                stg_desc = item['paradesc']
                if not Paperstgpara.objects.filter(stgid=stgid, propkey=stg_name).exists():
                    Paperstgpara.objects.create(
                        stgid=stgid,
                        propkey=stg_name,
                        propvalue=stg_value,
                        description=stg_desc,
                        proptype='',
                        provalueitems='',
                        updatetime=chardate(),
                    )
            # 日志操作 上传策略
            stgname = json.loads(data["stgname"])[0]
            stggroup = json.loads(data["stggroup"])[0]
            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '1',
                'optinfo': '上传策略成功，策略ID：%s，策略名称：%s，策略类型：%s，参数名：%s，参数值：%s' % (
                    stgid, stgname, stggroup, stg_name, stg_value),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict),
            return HttpResponse("y")


class PaperApproval(Paper):
    '''
    仿真策略审批
    '''

    def __init__(self):
        super(PaperApproval, self).__init__()
        self.title = '仿真策略审批'
        self.url = '/trade/paper_approval'
        self.opt = '仿真策略审批'

    def post(self, request):

        # 审批通过，更改审批状态，打包状态
        if request.POST.get('approval', None):
            stgid = int(request.POST.get('id'))  # int(str)
            stg = Strategy.objects.filter(stgid=stgid)[0]
            stgname = stg.stgname
            stggroup = stg.stggroup
            envs = Environment.objects.filter(type=1)

            Paperapproval.objects.filter(stgid=stgid).update(
                auditstatus='3',
                packstatus='0',
                updatetime=chardate(),
            )
            for env in envs:
                runpath = ''
                runpath_list = list(Environment.objects.filter(envid=env.envid).values_list('runpath'))
                if runpath_list is not None and len(runpath_list) != 0:
                    for item in runpath_list:
                        runpath_env = list(item)[0]
                        runpath = runpath_env + str(stgid)
                        # print(runpath) #F:\eryi\sxzq\10001

                # 运行表，根据环境表中type==1的条数生成记录
                Paperrun.objects.create(
                    stgid=stgid,
                    creattime=chardate(),
                    starttime='',
                    endtime='',
                    envid=env.envid,
                    runstatus='4',
                    runmsg='',
                    isavailable=-1,
                    stoptime='',
                    runpath=runpath,

                )

            customerid = ''
            stgid_list = list(Strategy.objects.filter(stgid=stgid).values_list('customerid'))
            for item in stgid_list:
                customerid = list(item)[0]
            # 用户表
            # 更新或者修改
            if not CustomerPaper.objects.filter(customerid=str(stgid)).exists():
                CustomerPaper.objects.create(
                    customerid=str(stgid),
                    customername='',
                    password='',
                    isactive=1,
                    maxlogined=1000,
                    usertype=8,
                    createtime=chardate(),
                    updatetime=chardate(),
                )

            # 分账户表，customerid == stgid
            if not CustomerchannelrelPaper.objects.filter(customerid=str(stgid)).exists():
                CustomerchannelrelPaper.objects.create(
                    customerid=str(stgid),
                    tdchannelid='Stc_api_sim',
                    mdchannelid='Stc_api_sim',
                    accountid=str(stgid),
                    assetno=str(stgid),
                    combino=str(stgid),
                    tdapitype='b',
                    apiaccountid='',
                    apiinvestorid=customerid,

                )
            # 策略表--rule表
            # ruleid唯一标识一条记录
            if not RulePaper.objects.filter(ruleid=stgid).exists():
                RulePaper.objects.create(
                    ruleid=stgid,
                    rulepath='',
                    ruleversion='',
                    rulename=stgname,
                    ruletype=stggroup,
                    configpath='',
                    customerid=str(stgid),
                    isclientloaded=1,
                )

            # 操作日志：仿真审批	审批策略：包括两种，审批仿真策略、审批实盘策略。记录审批人、审批策略ID、审批时间、审批结果
            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '4',
                'optinfo': '仿真审批通过，策略ID：%s，审批人：%s，审批时间：%s，审批结果：%s' % (stgid, customerid_log, chardate(), '审批通过'),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict),
            return HttpResponse('y')
        # 驳回
        else:
            data = request.POST
            stgid = int(request.POST.get('id'))  # int(str)
            stg = Strategy.objects.filter(stgid=stgid)[0]
            stgname = stg.stgname
            stggroup = stg.stggroup
            Paperapproval.objects.filter(stgid=stgid).update(
                auditstatus='2',
                auditmsg=json.loads(data["data[auditmsg]"])[0],
                updatetime=chardate(),
            )
            customerid_log = request.session.get('id', 'noCid')
            log_dict = {
                'customerid': customerid_log,
                'modular': '1',
                'optfunction': '4',
                'optinfo': '仿真审批驳回，策略ID：%s，审批人：%s，审批时间：%s，审批结果：%s' % (stgid, customerid_log, chardate(), '审批驳回'),
                'opttime': chardate(),
            }
            OperationLog.opt_log(log_dict),
            return HttpResponse('y')


## 监控页面的修改策略参数
def alterpara(request):
    try:
        ruleid = request.POST.get("ruleid")
        paraname = request.POST.get("paraname")
        paravalue = request.POST.get("paravalue")
        paradesc = request.POST.get("paradesc")
        paratype = request.POST.get("paratype")
        valueitems = request.POST.get("valueitems")
        updatetime = chardate()
        print(ruleid, "    ", paraname, "   ", paravalue, "   ", paradesc, "  ", valueitems, "  ", updatetime, "   ")
        Paperstgpara.objects.filter(stgid=int(ruleid)).update(
            propkey=paraname,
            propvalue=paravalue,
            proptype=paratype,
            provalueitems=valueitems,
            description=paradesc,
            updatetime=updatetime
        )
        return JsonResponse("y", safe=False)
    except Exception as e:
        print(e)
        return JsonResponse("服务器错误！", safe=False)
